<?php
/**
 * Класс для управления проект - специфичными кэшированными данными
 * 
 * @package    Forum Lite
 * @subpackage model
 * @author     sensey
 * @version    SVN: $Id: Builder.php 7490 2010-03-29 19:53:27Z jwage $
 */ 
class cacheRuler extends Doctrine_Cache_Xcache {
  /**
   * Переменная для хранения экземпляра объекта
   * @var Doctrine_Cache_Xcache
   */
  protected static $self;	
  /**
   * Ключ для хранения списка пользователей "id" => "login" 
   * @var string
   */
	protected $var_user = "users";
	/**
	 * Ключ для хранения количества пользователей в системе
	 * @var int
	 */
	protected $var_user_count = "users_count";
	/**
	 * Ключ для хранения количества комментариев в системе
	 * @var int
	 */
	protected $var_comments = "comments";
	/**
	 * Ключ для хранения количества комментариев созданных сегодня 
	 * @var array "post_id" => "comments_count"
	 */
	protected $var_comments_today = "comments_today";
	/**
	 * Ключ для общего количества комментариев созданных сегодня
	 * @var int
	 */
	protected $var_comments_today_count = "comments_today_count";
	/**
	 * Ключ для хранения комментариев созданных вчера
   * @var array "post_id" => "comments_count"
	 */
  protected $var_comments_yesterday = "comments_yesterday";
  /**
   * Ключ для хранения общего количества комментариев созданнх вчера
   * @var unknown_type
   */
  protected $var_comments_yesterday_count = "comments_yesterday_count";	
	
  /**
   * Метод для полученя экземпляра объекта
   * @return object cacheRuler
   */
	static public function instance ()
	{
		if(!is_object(self::$self))
		  if(!self::$self instanceof Doctrine_Cache_Xcache)
		      self::$self = new cacheRuler();
        return self::$self;		      
	}
  /**
   * Получение общего количества комментариев
   * @return int
   */
	public function getCommentsCount()
	{
    $count = $this->fetch($this->var_comments);
    if(is_numeric($count))
      return $count;
    $query = Doctrine_Query::create()->select ( 'COUNT(*) as count' )->from ( 'comment' );
    $count = $query->execute(array (), Doctrine_Core::HYDRATE_SCALAR);
    $count = array_shift($count);
    $count = $count["comment_count"];
    $this->save($this->var_comments, $count, sfConfig::get('app_comment_cache_lifetime'));
    return $count;		
	}
  /**
   * Очистить кэш комментариев
   */	
	public function clearCommentCache ()
	{
    $this->delete($this->var_comments_today);
    $this->delete($this->var_comments_today_count);
        
    $this->delete($this->var_comments_yesterday);
    $this->delete($this->var_comments_yesterday_count);
        
    return true;
  }
  /**
   * Получить количество комментарив за сегодня
   * @return int 
   */  
  public function getCommentsTodayCount ()
  {
    $count = $this->fetch($this->var_comments_today_count);
    if(!is_null($count))
    {
      $this->getTodayCommentsCache();
      $count = $this->fetch($this->var_comments_today_count);
    }
    return $this->fetch($this->var_comments_today_count);        
  }	
  /**
   * Получить количество комментариев у разных топиков 
   * из кэша, если кэш пустой, делается выборка из базы данных и 
   * значения сохраняются в кэше в виде post_id=>comments_count массива
   * так же сохраняется общее количество комментариев за сегодня
   * @return array 
   */	
	public function getTodayCommentsCache ()
	{
       $comments = $this->fetch($this->var_comments_today);
       
       if(is_array($comments))
            return $comments;
            
        $res = self::getCommentsCountByDate (date("U", mktime(0,0,0,date("m"), date("d"), date("Y"))));            
            
        $lifetime = sfConfig::get('app_comment_cache_lifetime');
        $this->save($this->var_comments_today, $res, $lifetime);
        
        $count = 0;
        foreach($res as $comment)
          $count += $comment["comment_comments"];
          
        $this->save($this->var_comments_today_count, $count, $lifetime);
        
        return $res;		
	}
	/**
	 * Получить количество комментариев за вчера
   * @return int 
	 */
  public function getCommentsYesterdayCount ()
  {
    $count = $this->fetch($this->var_comments_yesterday_count);
    if(!is_null($count))
    {
      $this->getYesterdayCommentsCache();
      $count = $this->fetch($this->var_comments_yesterday_count);
    }
    return $this->fetch($this->var_comments_yesterday_count);        
  }	
  /**
   * Получить количество комментариев у разных топиков 
   * из кэша, если кэш пустой, делается выборка из базы данных и 
   * значения сохраняются в кэше в виде post_id=>comments_count массива;
   * так же сохраняется общее количество комментариев за вчера
   * @return array 
   */
  public function getYesterdayCommentsCache ()
  {
    $comments = $this->fetch($this->var_comments_yesterday);
       
    if(is_array($comments))
      return $comments;
            
    $res = self::getCommentsCountByDate (date("U", mktime(0,0,0,date("m"), date("d")-1, date("Y"))));            

    $lifetime = sfConfig::get('app_comment_cache_lifetime');
        
    $this->save($this->var_comments_yesterday, $res, $lifetime);
        
    $count = 0;
    foreach($res as $comment)
      $count += $comment["comment_comments"];        
        
    $this->save($this->var_comments_yesterday_count, $count, $lifetime);
                
    return $res;        
  }	
  /**
   * Получить количество комментариев для каждого топика в виде массива post_id => comments_count
   * @param unix_timestamp $date
   */	
  public function getCommentsCountByDate ($date)
  {
    $query = Doctrine_Query::create()
      ->select ( 'COUNT(*) as comments, post_id ' )
      ->from ( 'comment' )
      ->where("UNIX_TIMESTAMP(DATE_FORMAT(created_at, \"%Y-%c-%d\")) = ?", $date)
      ->groupBy("post_id");
    $comments = $query->execute ( array (), Doctrine_Core::HYDRATE_SCALAR );
        
    $res = array ();
    foreach ($comments as $comment)
      $res[$comment["comment_post_id"]] = $comment["comment_comments"];

    return $res;
  }
  /**
   * Получить количество пользователей в системе
   * @return int 
   */
  function getUserCount ()
  {
    $count = $this->fetch($this->var_user_count);
    if(!is_null($count))
    {
      $this->getUserCache();
      $count = $this->fetch($this->var_user_count);    		
    }
    return $count;
  }
  /**
   * Получить массив пользователей user_id=>login
   * @return array 
   */
  function getUserCache () {
    $users = $this->fetch($this->var_user);
    
    if(is_array ($users) && count($users))
      return $users;
            
    $query = Doctrine_Query::create()->select ( 'id, login' )->from ( 'user' );
      
    $users = $query->execute(array (), Doctrine_Core::HYDRATE_SCALAR);

    $res = array ();
    foreach ($users as $user)
      $res[$user["user_id"]] = $user["user_login"];

    $lifetime = sfConfig::get('app_user_cache_lifetime');            
            
    $this->save($this->var_user, $res, $lifetime);
    $this->save($this->var_user_count, count($res), $lifetime);
    return $res;
  }
  /**
   * Очистить кэш с данными о пользователях 
   * @return array 
   */  
  public function clearUserCache ()
  {
    $this->delete($this->var_user);
    $this->delete($this->var_user_count);
    return true;
  }    
}

?>